package cn.kduck.assembler.security.authentication;

import cn.kduck.core.cache.CacheHelper;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.util.StringUtils;

import static cn.kduck.assembler.security.authentication.PhoneNumAuthenticationToken.ACCOUNT_PREFIX;

public class PhoneNumAuthenticationProvider implements AuthenticationProvider {

    private final UserNameService userNameService;
    private final UserDetailsService userDetailsService;

    public PhoneNumAuthenticationProvider(UserNameService userNameService, UserDetailsService userDetailsService){
        this.userNameService = userNameService;
        this.userDetailsService = userDetailsService;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        PhoneNumAuthenticationToken phoneNumToken = (PhoneNumAuthenticationToken) authentication;
        Object principal = phoneNumToken.getPrincipal();
        Object phoneNum = principal.toString().substring(ACCOUNT_PREFIX.length());
        Object captchaCode = phoneNumToken.getCaptchaCode();

        String savedCaptchaCode = (String) CacheHelper.getByCacheName(PhoneNumAuthenticationFilter.class.getSimpleName() , phoneNum);

        if(StringUtils.hasText(savedCaptchaCode) && savedCaptchaCode.equals(captchaCode)){
            String userName = userNameService.getUserName(AuthenticationType.PHONE_NUM, phoneNum);
            UserDetails userDetails = userDetailsService.loadUserByUsername(userName);

            UsernamePasswordAuthenticationToken authenticatedToken = new UsernamePasswordAuthenticationToken(userDetails,
                    phoneNum,userDetails.getAuthorities());

            CacheHelper.evict(PhoneNumAuthenticationFilter.class.getSimpleName(),phoneNum);

            return authenticatedToken;
        }

        throw new BadCaptchaException("认证失败，验证码错误");
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return PhoneNumAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
